home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr50 / s3bas11.zip / PORT.BAS < prev    next >
BASIC Source File  |  1993-05-02  |  8KB  |  229 lines

  1. 'Example of using the word functions that are in the
  2. 'WORD.BAS file to manipulate the I/O ports.
  3. '
  4. 'By:  George Spafford Copyright 1993
  5. '
  6. 'No additional libraries required
  7. '
  8. 'v1.0  05/02/93
  9. '
  10. '**************************************************
  11.  
  12. 'If you use these routines, please have the courtesy
  13. 'of registering the tutorial.
  14.  
  15. 'Make sure that you have all of your variables typed
  16. 'correctly before you use one of the following
  17. 'routines.  Use integers where integers are identified (%).
  18. 'Use long integers where long integers are identified (&).
  19.  
  20. 'Int2Long& is a function that accepts a signed
  21. 'integer and returns an unsigned long integer. Since
  22. 'BASIC uses the high bit to toggle the sign of an
  23. 'integer, you must convert it to a long integer before
  24. 'you perform any bit operations on it.
  25.  
  26. DECLARE FUNCTION Int2Long& (IntNumber%)
  27.  
  28. 'BASIC does NOT have a built in facility to PEEK
  29. 'words!  Tell the PeekWord% function where to look,
  30. 'and it will read in a word at that segment and offset.
  31.  
  32. DECLARE FUNCTION PeekWord% (Segment%, Offset%)
  33.  
  34. 'As with Peeks, BASIC does not support a POKE function
  35. 'for words.  This next subroutine adds that capability.
  36. 'Tell the subroutine the segment, offset and word that
  37. 'you wish it to POKE in and it will do so.
  38.  
  39. DECLARE SUB PokeWord (Segment%, Offset%, Word%)
  40.  
  41. 'As you code more and more programs, try to make your code
  42. 'as modular as possible.  By creating objects (OOP systems),
  43. 'you can significantly increase your code reusability.
  44. 'Try to only create the wheel once!  Some of the demos would
  45. 'benefit greatly by judicial use of subroutines.  In order to
  46. 'have top-down readability, I did not modularize the code.
  47. 'Just a FYI   -- George
  48.  
  49. DEFINT A-Z
  50. Title$ = "S3 Demo of WORD functions and I/O ports           Copyright George Spafford 1993"
  51.  
  52. Main:
  53.     CLS
  54.     PRINT Title$
  55.     LOCATE 3, 30: PRINT "To enter hexadecimal numbers, prefix your answer"
  56.     LOCATE 4, 30: PRINT "with &H.  For example, &H400 represents 400 Hex."
  57.     LOCATE 3, 1
  58.     GOSUB ReadPorts
  59.     PRINT "Menu     Port   Address"
  60.     PRINT "----     ----   -------"
  61.     PRINT " 1.      COM1:  "; HEX$(COM1); " Hex"    'HEX$ formats numeric
  62.     PRINT " 2.      COM2:  "; HEX$(COM2)            'input to a hexadecimal
  63.     PRINT " 3.      COM3:  "; HEX$(COM3)            'string representation
  64.     PRINT " 4.      COM4:  "; HEX$(COM4)
  65.     PRINT " 5.      LPT1:  "; HEX$(LPT1)
  66.     PRINT " 6.      LPT2:  "; HEX$(LPT2)
  67.     PRINT " 7.      LPT3:  "; HEX$(LPT3)
  68.     PRINT " 8.      LPT4:  "; HEX$(LPT4)
  69.     PRINT "======================="
  70.     PRINT
  71.     PRINT "Please select an option:"
  72.     PRINT
  73.     INPUT "(D)elete   (E)dit   (S)wap   (Q)uit:  ", Ans$
  74.     Ans$ = LTRIM$(RTRIM$(UCASE$(Ans$)))             'trim spaces and make the
  75.                                                     'answer upper case.
  76.     IF Ans$ = "" THEN PRINT : PRINT : END           'if answer is NULL then end
  77.  
  78.     'Just a note regarding efficiency when conditions are involved:
  79.     'If you have more than a couple of repetitive tasks to test, use
  80.     'the SELECT CASE method.  IF THEN statements require converting and
  81.     'testing a condition each time.  A select only has to convert the test
  82.     'variable once and then evaluate it against all of the answers.
  83.     'Taking this approach one step further, if you can use integer varaibles,
  84.     'then the test is even faster.  In the instance below, speed is not a
  85.     'factor, readability is.
  86.  
  87.     SELECT CASE Ans$
  88.            CASE "D"
  89.                 PRINT
  90.                 INPUT "Delete which port:  ", Del$
  91.                 Del$ = LTRIM$(RTRIM$(Del$))
  92.                 IF Del$ <> "" THEN
  93.                    Value = VAL(Del$)
  94.                    GOSUB Choice
  95.                    IF Offset <> 0 THEN
  96.                       CALL PokeWord(0, Offset, 0)
  97.                    END IF
  98.                 END IF
  99.            CASE "E"
  100.                 PRINT
  101.                 INPUT "Edit which port:  ", Edit$
  102.                 Edit$ = LTRIM$(RTRIM$(Edit$))
  103.                 IF Edit$ <> "" THEN
  104.                    PRINT
  105.                    Value = VAL(Edit$)
  106.                    GOSUB Choice
  107.                    IF Offset <> 0 THEN
  108.                       INPUT "New value:  ", NewValue
  109.                       CALL PokeWord(0, Offset, NewValue)
  110.                    END IF
  111.                 END IF
  112.            CASE "S"
  113.                 PRINT
  114.                 INPUT "Swap port one:  ", From$
  115.                 Value = VAL(From$)
  116.                 GOSUB Choice
  117.                 FromAddr = Addr
  118.                 FromOffset = Offset
  119.                 INPUT "Swap port two:  ", To$
  120.                 Value = VAL(To$)
  121.                 GOSUB Choice
  122.                 ToAddr = Addr
  123.                 ToOffset = Offset
  124.                 IF ToOffset <> 0 AND FromOffset <> 0 THEN
  125.                    CALL PokeWord(0, ToOffset, FromAddr)
  126.                    CALL PokeWord(0, FromOffset, ToAddr)
  127.                 END IF
  128.            CASE "Q"
  129.                 PRINT : PRINT : END
  130.     END SELECT
  131.     GOTO Main
  132.     END
  133.  
  134. Choice:
  135.     Addr = 0
  136.     SELECT CASE Value
  137.            CASE 1
  138.                 Addr = COM1
  139.                 Offset = COM1off
  140.            CASE 2
  141.                 Addr = COM2
  142.                 Offset = COM2off
  143.            CASE 3
  144.                 Addr = COM3
  145.                 Offset = COM3off
  146.            CASE 4
  147.                 Addr = COM4
  148.                 Offset = COM4off
  149.            CASE 5
  150.                 Addr = LPT1
  151.                 Offset = LPT1off
  152.            CASE 6
  153.                 Addr = LPT2
  154.                 Offset = LPT2off
  155.            CASE 7
  156.                 Addr = LPT3
  157.                 Offset = LPT3off
  158.            CASE 8
  159.                 Addr = LPT4
  160.                 Offset = LPT4off
  161.            CASE ELSE
  162.                 Addr = 0
  163.                 Offset = 0
  164.     END SELECT
  165.  
  166.  
  167. ReadPorts:
  168.     'The BIOS data area starts at 0000:0400.  The first
  169.     '16 bytes of it concerns the I/O ports.  If the port
  170.     'is enabled, there will be a word entry that describes
  171.     'the I/O address where data should be sent when that device
  172.     'is used.  If the word is 0, then the device has not been
  173.     'recognized.  If a value is forced, then the system will
  174.     'recognize that port whether it truly exists or not.
  175.     'For example, some systems do not automatically scan
  176.     'for COM3 and COM4 at POST (Power On Self-Test) time.  You
  177.     'must enter the address manually for that port if you
  178.     'need to use it in those instances.
  179.  
  180.     COM1off = &H400                     'Save Offset
  181.     COM1 = PeekWord%(0, COM1off)        'Get I/O address used
  182.     COM2off = &H402
  183.     COM2 = PeekWord%(0, COM2off)
  184.     COM3off = &H404
  185.     COM3 = PeekWord%(0, COM3off)
  186.     COM4off = &H406
  187.     COM4 = PeekWord%(0, COM4off)
  188.     LPT1off = &H408
  189.     LPT1 = PeekWord%(0, LPT1off)
  190.     LPT2off = &H40A
  191.     LPT2 = PeekWord%(0, LPT2off)
  192.     LPT3off = &H40C
  193.     LPT3 = PeekWord%(0, LPT3off)
  194.     LPT4off = &H40E
  195.     LPT4 = PeekWord%(0, LPT4off)
  196.     RETURN
  197.  
  198. DEFSNG A-Z
  199. FUNCTION Int2Long& (IntNumber%)
  200.     'If the integer is negative, we need to add 65536
  201.     'to the number (which is 2 * integer limit) to get
  202.     'our new long integer.
  203.  
  204.     IF IntNumber% < 0 THEN
  205.        Int2Long& = 65536 + IntNumber%
  206.     ELSE
  207.        Int2Long& = IntNumber%
  208.     END IF
  209. END FUNCTION
  210.  
  211. FUNCTION PeekWord% (Segment%, Offset%)
  212.     DEF SEG = Segment%              'set segment
  213.     High = PEEK(Offset% + 1)        'High byte is at offset + 1
  214.     Low = PEEK(Offset%)             'Low byte is at offset  
  215.     PeekWord% = (High * 256) + Low  'Compute the word value
  216.     DEF SEG                         'return to default segment
  217. END FUNCTION
  218.  
  219. SUB PokeWord (Segment%, Offset%, Word%)
  220.     DEF SEG = Segment%          'Set segment
  221.     High = (Word% \ 256)        'perform integer division
  222.                                 'to compute the high byte
  223.     Low = Word% - (High * 256)  'compute the low byte
  224.     POKE (Offset% + 1), High    'POKE in the high byte
  225.     POKE Offset%, Low           'POKE in the low byte
  226.     DEF SEG                     'return to the default segment
  227. END SUB
  228.  
  229.